import {
	MQTT_INFO
} from './constant';
import mqttTool from '../lib/mqttTool.js'

import { v4 as uuidv4 } from 'uuid';

export default  class MQTT {
	instance; 
	mqclient;
	brokerHost; 
	brokerPort; 
	subscribeTopics; 
	subscribeCallbacks; 

	constructor(host, port) {
		this.brokerHost = host;
		this.brokerPort = port;
		this.subscribeTopics = new Array ();
		this.subscribeCallbacks = new Map ();
	}

	// 单例模式
	   static getInstance() {
		if (!MQTT.instance) {
			MQTT.instance = new MQTT(
				MQTT_INFO.host,
				// MQTT_INFO.protocol ? 8084 : 8083,
				1883
			);
			MQTT.instance.connect({
				username: MQTT_INFO.username,
				password: MQTT_INFO.password,
				clientId:  uuidv4(),
				clean: MQTT_INFO.clean,
				// protocol: MQTT_INFO.protocol ? 'wss' : 'ws',
			});
		}
		return MQTT.instance;
	}

	/**
   * 订阅主题
   * 
	topic: string, qos: 0 | 1 | 2
   */
	 subscribe(topic, qos) {
		 console.log('mqtt订阅', topic, qos);
		const findIndex = this.subscribeTopics.findIndex(item => item.topic === topic);
		// console.log('findIndex', findIndex);
		if (findIndex === -1) {
			this.subscribeTopics.push({
				topic,
				qos
			});
			if (this.is_connected()) {
				this.mqclient.subscribe(topic, {
					qos
				});
			}
		}
	}

	/**
	 * 设置消息数据回调函数
	 */
	 set_message_callback(topicPatten, cb) {
		this.subscribeCallbacks.set(topicPatten, cb);
	}

	/**
	 * 是否已连接到服务器
	 */
	 is_connected() {
		return this.mqclient && this.mqclient.connected == true;
	}

	/**
	 * 连接到服务器
	 */
	 async connect(opts) {
		let brokerUrl = `ws://${this.brokerHost}:${this.brokerPort}/mqtt`;
		// #ifdef APP-PLUS
		brokerUrl = `wx://${this.brokerHost}:${this.brokerPort}/mqtt`;
		// #endif
		this.mqclient = await mqttTool.connect({
			...opts,
			url: brokerUrl,
		});
		
		this.mqclient.on('connect', (res) => {
			console.log('%c [ 连接成功 ]-95', 'font-size:13px; background:#0b5084; color:#4f94c8;', res)
			for (let index = 0; index < this.subscribeTopics.length; index++) {
				const element = this.subscribeTopics[index];
				this.mqclient.subscribe(element.topic, {
					qos: element.qos
				});
			}
		})
		this.mqclient.on('reconnect', (res) => {
			console.log('%c [ 重新连接 ]-99', 'font-size:13px; background:#954ca2; color:#d990e6;', res)
		})
		this.mqclient.on('error', (res) => {
			console.log('%c [ 连接错误 ]-103', 'font-size:13px; background:#f041ee; color:#ff85ff;', res)
		})
		this.mqclient.on('close', (res) => {
			console.log('%c [ 关闭成功 ]-107', 'font-size:13px; background:#91b31b; color:#d5f75f;', res)
		})
		this.mqclient.on('message', (topic, message, buffer) => {
			// console.log('%c [ topic ]-107', 'font-size:13px; background:#65d68e; color:#a9ffd2;', topic)
			// console.log('%c [ buffer ]-108', 'font-size:13px; background:#15d729; color:#59ff6d;', buffer)
			// console.log('%c [ message ]-108', 'font-size:13px; background:#66f35d; color:#aaffa1;', message)
			this.subscribeCallbacks.forEach((val, key) => {
				let reg = new RegExp(key.replace(/(\+|#)/g, '.*'));
				if (reg.test(topic)) {
					val(topic, message);
				}
			});
		})
	}

	/**
	 * 推送数据
	 * (topic: string, message: string, qos: 0 | 1 | 2)
	 */
	 publish(topic, message, qos) {
		this.mqclient?.publish(topic, message, {
			qos: qos,
			retain: false
		});
	}

	/**
	 * 结束连接
	 */
	 onEnd() {
		this.mqclient?.end();
	}

	/**
	 * 取消订阅主题
	 */
	 unsubscribe(topic) {
		console.log('mqtt取消订阅', topic);
		const findIndex = this.subscribeTopics.findIndex(item => item.topic === topic);
		if (findIndex !== -1) {
			this.subscribeTopics.splice(findIndex, 1);
		}
		this.mqclient?.unsubscribe(topic);
	}
}